#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/11/2 11:36
# @Author  : CHEN Wang
# @Site    : 
# @File    : db_conn.py
# @Software: PyCharm

"""
脚本说明: 获取业务数据库连接

注：创建连接支持关键字参数by_sqlalchemy
   支持通过过sqlalchemy.creat_engine创建，或者通过pymysql的方式创建， 默认False即使用pymysql
"""

from quant_researcher.quant.project_tool.conf import LOCAL_CONF
from quant_researcher.quant.project_tool.logger.my_logger import LOG
from quant_researcher.quant.project_tool.db_operator import my_redis
from quant_researcher.quant.project_tool.db_operator.my_mysql import get_mysql_conn_by_name

FACTOR_DB_CONN = None


def get_global_basic_data_conn(**kwargs):
    """
    本脚本其他Mysql数据库连接创建函数均是先创建数据库连接，用完再关闭
    该函数会在第一次被调用时创建数据库连接，赋值给一个全局变量，之后再被调用时会直接使用该全局变量作为数据库连接
    相比之下，节省了数据库每次创建再关闭的时间
    但是在公司环境连托管机房的数据库时，几十分钟后数据库连接会被自动断开，用此函数会导致之后数据库一直连不上

    :return:
    """
    global FACTOR_DB_CONN
    if FACTOR_DB_CONN is None:
        LOG.warning('👮 Python的多进程编程主要依赖multiprocessing库，'
                    '父进程的参数直接拷贝给子进程，'
                    '但因为Linux进程的copy on write特性，'
                    '如果子进程不对参数进行修改就不会进行拷贝工作，'
                    '那么父进程，子进程共享参数。'
                    '而参数的返回则通过管道pipe进行。')
        LOG.warning('👮 FACTOR_DB_CONN：'
                    '对于一个Windows进程，你应该只会看到这个信息 最多 一次'
                    '( Linux 与 Windows 对多进程不同)')
        FACTOR_DB_CONN = get_basic_data_conn(**kwargs)
    return FACTOR_DB_CONN


def get_basic_data_conn(**kwargs):
    """
    基础数据组创建并维护的基金基础数据库

    :param kwargs:
        - bool creat_engine: 是否是通过sqlalchemy.creat_engine创建，还是通过pymysql的方式创建， 默认False即使用pymysql
    :return:
    """
    CON = get_mysql_conn_by_name('basic_data', cn_name='公募基金基础数据库', **kwargs)
    return CON


def get_tk_factors_conn(**kwargs):
    """
    投研组创建并维护的因子数据库

    :return:
    """
    CON = get_mysql_conn_by_name('tk_factors', cn_name='投研因子数据库', **kwargs)
    return CON


def get_tk_factors_write_db_conn(**kwargs):
    """
    基金衍生指标数据库写入操作

    :return:
    """
    return get_mysql_conn_by_name('tk_factors_write', cn_name='因子结果写入', **kwargs)


def get_third_party_conn(**kwargs):
    """
    第三方数据库，目前是龙柏的基础数据库

    :return:
    """
    return get_mysql_conn_by_name('third_party', cn_name='第三方基础数据库', **kwargs)


def get_stock_conn(**kwargs):
    """
    基础数据组加工再创建的股票基础数据库

    :return:
    """
    return get_mysql_conn_by_name('stock', cn_name='股票基础数据库', **kwargs)


def get_stock_test_conn(**kwargs):
    """
    基础数据组加工再创建的股票基础数据测试库

    :return:
    """
    return get_mysql_conn_by_name('stock_test', cn_name='股票基础数据测试库', **kwargs)


def get_derivative_data_conn(**kwargs):
    """
    衍生指标数据库

    :return:
    """
    return get_mysql_conn_by_name('derivative_data', cn_name='衍生指标结果', **kwargs)


def get_derivative_data_write_conn(**kwargs):
    """
    基金衍生指标数据库写入操作

    :return:
    """
    return get_mysql_conn_by_name('derivative_data_write', cn_name='衍生指标结果写入', **kwargs)


def get_fof_conn(**kwargs):
    """
    组合数据库

    :return:
    """
    return get_mysql_conn_by_name('fof', cn_name='fof组合数据库', **kwargs)


def get_gs_conn(**kwargs):
    """
    国信数据库

    :return:
    """
    return get_mysql_conn_by_name('gs', cn_name='国信数据库', **kwargs)


# --- redis数据库创建 --- #

DEPLOY_MODE = LOCAL_CONF['factor-computation']['redis_deploy_mode']
URL = LOCAL_CONF['factor-computation']['redis_url']
PSWD = LOCAL_CONF['factor-computation']['redis_password']
DB = LOCAL_CONF['factor-computation']['redis_db']
MASTER = LOCAL_CONF.get('factor-computation', 'redis_master', fallback=None)


def redis_develop_write():
    if DEPLOY_MODE == 'sentinel':
        return my_redis.get_master(sentinel_url=URL, password=PSWD, db=DB, master=MASTER)
    elif DEPLOY_MODE == 'single':
        return my_redis.get_operator(url=URL, password=PSWD, db=DB)
    else:
        raise ValueError(f'錯誤的部署模式：{DEPLOY_MODE}')


def redis_develop_read():
    if DEPLOY_MODE == 'sentinel':
        return my_redis.get_slave(sentinel_url=URL, password=PSWD, db=DB, master=MASTER)
    elif DEPLOY_MODE == 'single':
        return my_redis.get_operator(url=URL, password=PSWD, db=DB)
    else:
        raise ValueError(f'錯誤的部署模式：{DEPLOY_MODE}')


def redis_develop_write_fof():
    return my_redis.get_operator(
        url=LOCAL_CONF['factor-computation']['redis_url_fof'],
        password=LOCAL_CONF['factor-computation']['redis_password_fof'],
        db=LOCAL_CONF['factor-computation']['redis_db_fof']
    )


if __name__ == '__main__':
    # conn = get_tk_factors_conn(by_sqlalchemy=True)
    conn = get_stock_test_conn()
